package Projektarbete;

import gui.*;

import java.awt.GridLayout;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Timer;

import javax.swing.DefaultListModel;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

import serverAndThreads.CT;
import serverAndThreads.CT.*;

import staticClasses.F;
import staticClasses.IP;
import staticClasses.Port;

public class ContactTabListFiller {
	/*
	 * �ndrad av Johan 02/05 kl:11:56
	 * 
	 * �ndrat: lagt �ver metoder som tillh�r ContactPanel i ContactPanel.
	 */

	@SuppressWarnings("unchecked")
	public ArrayList<User> getContactList(User user) {
		Socket socket;
		ArrayList<User> contactList = null;
		try {
			socket = new Socket(IP.getServerIP(), Port.getServerPort());

			ObjectOutputStream out = new ObjectOutputStream(
					socket.getOutputStream());
			ObjectInputStream in = new ObjectInputStream(
					socket.getInputStream());

			out.writeObject(F.GET_CONTACT_LIST);
			out.writeObject(user);

			/********************************************
			 * Denna metod skickar och tar * nu emot UserObjekt *
			 ********************************************/

			contactList = (ArrayList<User>) in.readObject();
			System.out
					.println("ContactTabListFiller	UserList recieved from server");
			System.out.println(contactList.toString());

			out.close();
			in.close();
			socket.close();

		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return contactList;
	}

	public boolean registerNewUser(User user) {
		Socket socket;
		try {
			socket = new Socket(IP.getServerIP(), Port.getServerPort());
			ObjectOutputStream out = new ObjectOutputStream(
					socket.getOutputStream());
			ObjectInputStream in = new ObjectInputStream(
					socket.getInputStream());

			out.writeObject(F.NEW_USER);
			out.writeObject(user);
			boolean bol = (Boolean) in.readObject();

			System.out.println("ContacTabListFiller:	new user sent");

			out.close();
			in.close();
			socket.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		return true;
	}

	@SuppressWarnings("unchecked")
	public ArrayList<User> getContactList() {
		System.out
				.println("WRONG METHOD!: ContactTabListFiller.getContactList()");
		ArrayList<User> contactList = null;
		try {
			Socket socket = new Socket(IP.getServerIP(), Port.getServerPort());
			ObjectOutputStream out = new ObjectOutputStream(
					socket.getOutputStream());
			ObjectInputStream in = new ObjectInputStream(
					socket.getInputStream());

			out.writeObject(F.GET_CONTACT_LIST);
			out.writeObject(new User(1, null, null, false, null, null, null, 0));

			/********************************************
			 * Denna metod skickar och tar * nu emot UserObjekt *
			 ********************************************/

			contactList = (ArrayList<User>) in.readObject();
			System.out
					.println("ContactTabListFiller	UserList recieved from server");
			System.out.println(contactList.toString());

			out.close();
			in.close();
			socket.close();

		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return contactList;
	}

	public void sendNewGroup(Group group) {
		try {
			Socket socket = new Socket(IP.getServerIP(), Port.getServerPort());
			ObjectOutputStream out = new ObjectOutputStream(
					socket.getOutputStream());
			ObjectInputStream in = new ObjectInputStream(
					socket.getInputStream());

			out.writeObject(F.CREATE_GROUP);
			out.writeObject(group);

			System.out
					.println("ContacTabListFiller:	new group sent to database");

			out.close();
			in.close();
			socket.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("unchecked")
	public ArrayList<Group> getContactGroupList(User user) {
		ArrayList<Group> groupList = new ArrayList<Group>();
		try {
			Socket socket = new Socket(IP.getServerIP(), Port.getServerPort());

			ObjectOutputStream out = new ObjectOutputStream(
					socket.getOutputStream());

			ObjectInputStream in = new ObjectInputStream(
					socket.getInputStream());

			out.writeObject(F.GET_GROUP_LIST);
			out.writeObject(user);

			groupList = (ArrayList<Group>) in.readObject();
			System.out.println("ContacTabListFiller:	grouplist recieved");
			System.out.println("Recieved group lsit: " + groupList.toString());

			out.close();
			in.close();
			socket.close();

		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return groupList;
	}

	public void loginUser(JTextField usernameInput, JPasswordField passInput,
			MainFrame mf, JCheckBox rememberCheckBox, LoginScreen thisFrame) {
		String userName = null;
		boolean empty = false;
		if (usernameInput.getText().isEmpty() || passInput.getText().isEmpty()) {
			empty = true;
		}

		if (empty) {
			JOptionPane.showMessageDialog(null,
					"Fill in both username and password.");
		} else {
			try {
				Socket socket = new Socket(IP.getServerIP(),
						Port.getServerPort());

				ObjectOutputStream out = new ObjectOutputStream(
						socket.getOutputStream());
				ObjectInputStream in = new ObjectInputStream(
						socket.getInputStream());

				out.writeObject(F.LOGIN);

				userName = usernameInput.getText();

				out.writeObject(userName);
				out.writeObject(passInput.getText());
				out.writeObject(IP.getMyIP());

				System.out.println("sent");
				// out.writeUTF(ip);

				writeCookies(rememberCheckBox, usernameInput.getText(),
						passInput.getText());

				User user = null;

				user = (User) in.readObject();
				System.out.println("Correct username? : " + (user != null));
				
				out.close();
				in.close();
				socket.close();

				if (user != null) {
					mf = new MainFrame(user);
					mf.setVisible(true);
					thisFrame.dispose();
				} else {
					JOptionPane.showMessageDialog(null,
							"Wrong username or password, try again!");
				}

				
			} catch (ClassNotFoundException e) {
				e.printStackTrace();

			} catch (IOException ioe) {
				JOptionPane.showMessageDialog(null,
						"Could not connect to Server.");
			}
		}

	}

	public void userLogOff(User user) {
		try {
			System.out.println("Im logging off");
			Socket socket = new Socket(IP.getServerIP(), Port.getServerPort());
			ObjectOutputStream out = new ObjectOutputStream(
					socket.getOutputStream());
			ObjectInputStream in = new ObjectInputStream(
					socket.getInputStream());

			user.setOnline(false);
			out.writeObject(F.LOGOUT);
			out.writeObject(user);

			out.close();
			socket.close();
		} catch (UnknownHostException e1) {
			e1.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}

	private void writeCookies(JCheckBox rememberCheckBox, String userNameInput,
			String passInput) throws IOException {

		if (rememberCheckBox.isSelected()) {

			PrintWriter pw = new PrintWriter(new FileWriter("cookies.txt"));
			pw.println(userNameInput);
			pw.println(passInput);
			pw.close();
		} else {
			PrintWriter pw = new PrintWriter(new FileWriter("cookies.txt"));
			pw.println("");
			pw.println("");
			pw.close();
		}
	}

	@SuppressWarnings("unchecked")
	public void removeContact(User user, ArrayList<User> removeList) {
		try {
			Socket socket = new Socket(IP.getServerIP(), Port.getServerPort());

			ObjectOutputStream out = new ObjectOutputStream(
					socket.getOutputStream());
			ObjectInputStream in = new ObjectInputStream(
					socket.getInputStream());

			out.writeObject(F.REMOVE_CONTACT);
			out.writeObject(user);
			out.writeObject(removeList);

			out.close();
			in.close();
			socket.close();

		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public boolean addContact(User user, String nameOrMail, MainFrame mf) {
		User contact = null;
		try {
			Socket socket = new Socket(IP.getServerIP(), Port.getServerPort());

			ObjectOutputStream out = new ObjectOutputStream(
					socket.getOutputStream());
			ObjectInputStream in = new ObjectInputStream(
					socket.getInputStream());

			out.writeObject(F.ADD_CONTACT);
			out.writeObject(user);
			out.writeObject(nameOrMail);

			contact = (User) in.readObject();

			if (contact != null) {

				mf.addSingleContact(contact);
			} else {
				System.out.println("NUUUULL");
			}

			/********************************************
			 * Denna metod skickar och tar * nu emot UserObjekt *
			 ********************************************/

			out.close();
			in.close();
			socket.close();
			return (contact != null);

		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return false;
	}

	public void updateGroup(Group group) {
		try {
			System.out.println("Im logging off");
			Socket socket = new Socket(IP.getServerIP(), Port.getServerPort());
			ObjectOutputStream out = new ObjectOutputStream(
					socket.getOutputStream());
			ObjectInputStream in = new ObjectInputStream(
					socket.getInputStream());

			out.writeObject(F.UPDATE_GROUP);
			out.writeObject(group);

			out.close();
			in.close();
			socket.close();
		} catch (UnknownHostException e1) {
			e1.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}
	
	public void saveStickyNote(int ID, String msg) {
		try {
			Socket socket = new Socket(IP.getServerIP(), Port.getServerPort());

			ObjectOutputStream out = new ObjectOutputStream(
					socket.getOutputStream());
			ObjectInputStream in = new ObjectInputStream(
					socket.getInputStream());
			

			out.writeObject(F.SAVE_STICKY_NOTE);
			out.writeObject(ID);
			out.writeObject(msg);

			out.close();
			in.close();
			socket.close();

		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void removeStickyNote(int ID,  String msg) {
		try {
			Socket socket = new Socket(IP.getServerIP(), Port.getServerPort());

			ObjectOutputStream out = new ObjectOutputStream(
					socket.getOutputStream());
			ObjectInputStream in = new ObjectInputStream(
					socket.getInputStream());
			
			String id = Integer.toString(ID);

			out.writeObject(F.REMOVE_STICKY_NOTE);
			out.writeObject(id);
			out.writeObject(msg);

			out.close();
			in.close();
			socket.close();

		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public ArrayList<String> getStickyNote(int ID) {
		ArrayList<String> message = new ArrayList<String>();
		try {
			Socket socket = new Socket(IP.getServerIP(), Port.getServerPort());

			ObjectOutputStream out = new ObjectOutputStream(
					socket.getOutputStream());
			ObjectInputStream in = new ObjectInputStream(
					socket.getInputStream());
			
			String id = Integer.toString(ID);

			out.writeObject(F.GET_STICKY_NOTE);
			out.writeObject(id);
			
			message = (ArrayList<String>) in.readObject();
			
			out.close();
			in.close();
			socket.close();

		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return message;
	}
	
	public ArrayList<User> searchUser(String searchWord) {
		ArrayList<User> searchList = new ArrayList<User>();
		try {
			Socket socket = new Socket(IP.getServerIP(), Port.getServerPort());

			ObjectOutputStream out = new ObjectOutputStream(
					socket.getOutputStream());
			ObjectInputStream in = new ObjectInputStream(
					socket.getInputStream());
			

			out.writeObject(F.SEARCH_USER);
			out.writeObject(searchWord);
			
			searchList =  (ArrayList<User>)in.readObject();

			out.close();
			in.close();
			socket.close();

		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return searchList;
	}

	public static class ClientThread implements Runnable {
		MainFrame mf;

		public ClientThread(MainFrame mf) {
			this.mf = mf;
		}

		private void newClientThread() {
			new Thread(new ClientThread(mf)).start();
		}

		@Override
		public void run() {
			System.out.println("Ruuuuunning");
			try {

				CT[] method = declareAbstractMethods();

				ServerSocket serverSocket = new ServerSocket(
						Port.getClientPort());

				Socket socket = serverSocket.accept();

				serverSocket.close();
				newClientThread();

				ObjectInputStream in = new ObjectInputStream(
						socket.getInputStream());
				ObjectOutputStream out = new ObjectOutputStream(
						socket.getOutputStream());

				int function = (Integer) in.readObject();
				method[function].perform(mf, in, out, socket);

				in.close();
				out.close();
				socket.close();

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

		private CT[] declareAbstractMethods() {
			CT[] ct = new CT[F.AMOUNT];
			ct[F.ADD_CONTACT] = new CT.AddContact();
			ct[F.UPDATE_ONLINE_STATUS] = new CT.UpdateOnlineStatus();
			ct[F.REMOVE_CONTACT] = new CT.RemoveContact();
			ct[F.ADD_TO_GROUP] = new CT.AddGroup();
			ct[F.REMOVE_FROM_GROUP] = new CT.RemoveGroup();

			return ct;

		}

	}
}